package com.asdhawaii.otello.players;

import java.util.List;
import com.asdhawaii.otello.board.Direction;
import com.asdhawaii.otello.board.Square;
import com.asdhawaii.otello.board.SquareContents;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import org.junit.Test;

/**
 * Tests the AbstractOtelloAi class and provides methods for more easily testing inheriting AIs.
 * 
 * @author Branden Ogata
 *
 */

public class TestAbstractOtelloAi
{
  /**
   * Tests the methods of the AbstractOtelloAi class.
   * 
   */
  
  @Test
  public void test()
  {
    // Uses Level0Ai since AbstractOtelloAi is abstract
    AbstractOtelloAi ai = new Level0Ai(SquareContents.BLACK);
    
    // Test if valid move looking in valid direction is valid
    Square[][] board = TestAbstractOtelloAi.createStartingBoard();
    assertTrue("Test valid move, valid direction", ai.isValidMove(board, 4, 3, Direction.S, "B"));
    
    // Test if valid move looking in invalid direction is invalid
    assertFalse("Test valid move, invalid direction", ai.isValidMove(board, 4, 3, 
                                                                     Direction.E, "B"));
    
    // Test if invalid move is invalid
    assertFalse("Test invalid move", ai.isValidMove(board, 0, 0, Direction.E, "B"));
    
    // Test if move collinear with what would be a valid move is invalid
    board[4][2].setContents(SquareContents.BLACK);
    assertFalse("Test invalid move on line with valid move", ai.isValidMove(board, 4, 1, 
                                                                            Direction.S, "B"));
  }

  /**
   * Returns a blank Otello board.
   * 
   * @return board A Square[][] with all squares empty.
   * 
   */
  
  protected static Square[][] createEmptyBoard()
  {
    Square[][] board = new Square[8][8];
    
    for (int i = 0; i < 8; i++)
    {
      for (int j = 0; j < 8; j++)
      {
        board[i][j] = new Square();
        board[i][j].setName(String.format("%d%d", i, j));
      }
    }
    
    return board;
  }
  
  /**
   * Returns the starting Otello board.
   * 
   * @return board A Square[][] with the starting Otello position.
   * 
   */
  
  protected static Square[][] createStartingBoard()
  {
    Square[][] board = createEmptyBoard();
    board[3][3].setContents(SquareContents.BLACK);
    board[3][4].setContents(SquareContents.WHITE);
    board[4][3].setContents(SquareContents.WHITE);
    board[4][4].setContents(SquareContents.BLACK);
    
    return board;
  }  
  
  /**
   * Returns a list comprised of the parameter values.
   * 
   * @param <E> The type for the List.
   * @param list The List<E> to assign values to.
   * @param values The E to place in the list.
   * 
   */
  
  protected static <E> void createList(List<E> list, E ... values)
  {
    list.clear();
    
    for (E element : values)
    {
      list.add(element);
    }
  }
}